package com.ccp.dev.qbdms.service;

import com.ccp.dev.core.util.AppUtil;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.extend.model.ExtendSysFile;
import com.ccp.dev.qbdms.consts.ZhiLiangConst;
import com.ccp.dev.qbdms.dao.CommonalityDao;
import com.ccp.dev.qbdms.model.BaseBusinessModel;
import com.ccp.dev.qbdms.model.SysOrgDeploy;
import com.ccp.dev.qbdms.model.WQbdFalProblemreset;
import com.ccp.dev.qbdms.util.ReadAttachmentUtil;
import com.ccp.dev.qbdms.webservice.cxf.CxfClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

import static com.ccp.dev.qbdms.consts.ZhiLiangConst.API_REPORT_PARA_LIST;

/**
 * Created by zzy on 2020/8/6.
 *
 * @Author zzy
 * @Date 2020/8/6
 * @describe 扩展一个通用上报,用于解决事务传播
 */
@Service
public class CommonalityExtendService {
    Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private CommonalityDao commonalityDao;
    @Resource
    private SysOrgDeployService sysOrgDeployService;
    @Resource
    private WQbdFalProblemresetService wQbdFalProblemresetService;
    @Resource
    private CommonalityService commonalityService;

    /** 质量问题模块对应的全小写classname */
    private final String MODEL_PROBLEM = "wqbdfalproblemreset";

    /**
     * 在处理前添加  xxx中 的状态
     * @author zzy
     * @param ids
     * @param status
     * @param tableName
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void addLocalStatusDoing(String ids, String status, String tableName){
        commonalityDao.reportPlant(tableName,ids.split(StringPool.COMMA),status);
    }

    /**
     * 处理前增加 xxx中状态,同时更新hospitalid字段
     * @param ids
     * @param status
     * @param tableName
     * @param hospitalCode
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void addLocalStatusDoing(String ids,String status,String tableName,String hospitalCode){
        commonalityDao.reportHospital(tableName, ids.split(StringPool.COMMA), status, hospitalCode);
    }

    /**
     * 归零处理
     * todo 搞成一个通用上报后处理方式
     * @author zzy
     * @param ids
     * @param modelName
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public boolean zeroHandler(String ids,String modelName,SysOrgDeploy dep) {
        // 在这里处理一下集中部署的自动归零,分级的自动归零在service-saveAll处理
        if (BeanUtils.isNotEmpty(dep) && ZhiLiangConst.DEPMETHOND_CLASS.equals(dep.getDepmethod())) {
            return false;
        }
        if (!modelName.toLowerCase().equals(MODEL_PROBLEM)) {
            return false;
        }
        if (BeanUtils.isEmpty(dep) || ZhiLiangConst.DEPMETHOND_CENTER.equals(dep.getDepmethod())) {
            try{
                wQbdFalProblemresetService.confirmZero(ids.split(StringPool.COMMA));
            }catch(Exception e){
                log.error("通用上报服务异常 -> 归零失败,跳过自动归零");
                return false;
            }
        }
        return true;
    }

    /**
     * 通用上报成功后处理方法,传入上报数据的id和上报模块对应的classname
     * @author zzy
     * @param ids
     * @param modelName
     */
    @Transactional(rollbackFor = Exception.class)
    public void reportSuccPostHandler(String ids,String modelName){
        modelName = modelName.toLowerCase();

        //2020/8/20 zzy 过滤质量问题信息,上报后更新updatetime字段
        if (modelName.equals(MODEL_PROBLEM)) {
            String[] idarr = ids.split(StringPool.COMMA);
            for (String id : idarr) {
                WQbdFalProblemreset model=wQbdFalProblemresetService.getParentAndChilden(id);
                model.setfUpdatetime(new Date());
                wQbdFalProblemresetService.update(model);
            }
        }
    }

    /**
     * 根据id获取完整数据,上报使用
     * @author
     * @param modelName
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    private Object getDataById(String modelName,String id,String mothodName) {
        modelName = CxfClient.getClassName(modelName);
        Object serviceBean = AppUtil.getBean(modelName+CxfClient.SERVICE);
        Class<? extends Object> cz = serviceBean.getClass();
        Method mh = ReflectionUtils.findMethod(cz,mothodName ,String.class );
        Object result = ReflectionUtils.invokeMethod(mh,serviceBean,id);
        return result;
    }

    /**
     * 获取多条数据
     * @author zzy
     * @param modelName
     * @param ids
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws ClassNotFoundException
     */
    private List<Object> getDataList(String modelName , String ids) {
        String[] businessIds = ids.split(StringPool.COMMA);
        List<Object> list = new ArrayList<>();
        for (String businessId : businessIds) {
            list.add(getDataById(modelName, businessId,ZhiLiangConst.REPGETONE));
        }
        return list;
    }

    /** 包装用来上报的参数,{list:数据集合,fileList:附件集合}
     * @author zzy
     * @param list
     * @return
     */
    private Map<String,Object> wrapParm(String ids,String status,String className){
        List<Object> list = getDataList(className, ids);

        Map<String, Object> parmMap = new HashMap<>(5);
        for (Object o : list) {
            ((BaseBusinessModel) o).setReportStatus(status);
        }
        Map<String,Object> param = new HashMap<>(3);
        param.put(API_REPORT_PARA_LIST,list);

        List<ExtendSysFile> fileList = ReadAttachmentUtil.getReport(param, className);
        if (BeanUtils.isNotEmpty(fileList)) {
            param.put(ZhiLiangConst.API_REPORT_PARA_LIST_FILE, fileList);
        }
        return parmMap;
    }


}
